import glog
from time import sleep
from abc import abstractclassmethod
import math


class BaseMonitor:
    def __init__(
        self, job_ids, recipe_email_users, query_interval_time, max_round=None
    ) -> None:
        """monitor jobid status

        Args:
            job_ids (str or list): e.g. dlc1efopadxxx or [dlc1efopxxxx, dlcxxxxx]
            recipe_email_users (str): e.g. "usera, userb"
            query_interval_time (int): monitor interval
        """
        self._job_ids = [job_ids] if not isinstance(job_ids, list) else job_ids
        self.valid_status = ["Failed", "Succeeded", "Deleted", "Stopping", "Stopped"]
        self._ids_cnt = len(self._job_ids)
        self.user_list = [
            i.strip() + "@deeproute.ai" for i in recipe_email_users.split(",")
        ]
        self.query_interval_time = query_interval_time
        self.max_round = math.inf if max_round is None else max_round

    def monitor(self):
        url_base = "http://pai-console.deeproute.cn:32080/index?projectId=&regionId=#/job/detail?jobId={}&page=jobs"
        iter_round = 0
        job_status_map = {}
        send_running_status = True
        while self._ids_cnt > 0 and iter_round < self.max_round:
            for id in self._job_ids:
                status, job_name, created_at, finished_at = self.single_monitor(id)
                if job_name:
                    job_status_map[job_name] = status

                if status == "Running" and send_running_status:
                    # while job is running, send msg to user/users[one time]
                    self.send_msg(
                        job_name,
                        url_base.format(id),
                        self.user_list,
                        status,
                        created_at,
                        "",
                    )
                    send_running_status = False
                if status in self.valid_status:
                    # while job was finished, send msg to user/users
                    self._ids_cnt -= 1
                    if len(self.user_list) > 0:
                        self.send_msg(
                            job_name,
                            url_base.format(id),
                            self.user_list,
                            status,
                            created_at,
                            finished_at,
                        )
            glog.info(
                f"Round {iter_round}, jobs status info: {job_status_map}, {self._ids_cnt} jobs is running."  # noqa
            )
            sleep(int(self.query_interval_time))
            iter_round += 1

    @abstractclassmethod
    def single_monitor(self, id):
        pass

    @abstractclassmethod
    def send_msg(self, jobname, url, user_list, status, created_at, finished_at):
        pass
